//babel库及文件模块导入
const fs = require('fs');

//babel库相关，解析，转换，构建，生产
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;

/*if (process.argv.length > 2) {
  encode_file = process.argv[2];
}
if (process.argv.length > 3) {
  decode_file = process.argv[3];
}*/



const visitor = 
{
  //TODO  write your code here！
  // StringLiteral:{
  //   enter: [replace_unicode]
  // },


}


//some function code
function replace_unicode(path) {
  delete path.node.extra;
}

// 处理十六进制、中英文Unicode字符串或数值
const transform_literal = {
  NumericLiteral({node}) {
    if (node.extra && /^0[obx]/i.test(node.extra.raw)) {
      node.extra = undefined;
    }
  },
  StringLiteral({node})
  {
    if (node.extra && /\\[ux]/gi.test(node.extra.raw)) {
      node.extra = undefined;
    }
  },
}

// MemberExpression和ObjectProperty key值Literal化
const member_property_literals = {
  MemberExpression: {
    exit({node}) {
      const prop = node.property;
      if (!node.computed && types.isIdentifier(prop)) {
        node.property = types.StringLiteral(prop.name);
        node.computed = true;
      }
    }
  },
  ObjectProperty: {
    exit({node}) {
      const key = node.key;
      if (!node.computed && types.isIdentifier(key)) {
        node.key = types.StringLiteral(key.name);
      }
    }
  },
}

// 优化无实参的自执行函数
const simplify_auto_exec = {
  UnaryExpression(path) {
    let {operator,argument} = path.node;
    if (operator != "!" || !types.isCallExpression(argument)) return;
    let {arguments,callee} = argument;
    if (arguments.length !=0 || !types.isFunctionExpression(callee)) return;

    let {id,params,body} = callee;
    if (id != null || params.length !=0 || !types.isBlockStatement(body)) return;
    path.replaceWithMultiple(body.body);
  },
}

// 简单函数混淆调用
const evaluate_global_func =
{
  "CallExpression"(path)
  {
    let {callee,arguments} = path.node;
    if (!types.isIdentifier(callee) || callee.name == "eval") return;
    if (!arguments.every(arg=>types.isLiteral(arg))) return;

    let func = global[callee.name];
    if (typeof func !== "function") return;

    let args = [];
    arguments.forEach((ele,index) =>{args[index] = ele.value;});
    // console.log(args);
    let value = func.apply(null,args);
    if (typeof value == "function") return;
    path.replaceInline(types.valueToNode(value));
  },
}


//读取文件
let encode_file = __dirname + "\\test_raw.js",
    decode_file = __dirname + "\\test_trans.js";

let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});
//转换为ast树
let ast = parser.parse(jscode);

//调用插件，处理源代码
// traverse(ast,visitor);
traverse(ast, evaluate_global_func)


//生成新的js code，并保存到文件中输出
let {code} = generator(ast, {jsescOption:{
	//自动转义中文
		minimal:true
	},
    // 删除注释
    comments: false
});
console.log(code);
// fs.writeFile(decode_file, code, (err)=>{});